const {
  ShapeFactory,
  Shape,
  Circle,
  Rectangle,
  Triangle
} = require("./template.js")

function testFactoryPattern() {
  console.log("=== 工厂模式测试 ===")

  console.log(
    "1. 创建圆形:",
    (() => {
      const factory = new ShapeFactory()
      const circle = factory.createShape("circle", 5)

      return (
        circle instanceof Circle &&
        circle.radius === 5 &&
        circle.type === "circle"
      )
    })()
  )

  console.log(
    "2. 创建矩形:",
    (() => {
      const factory = new ShapeFactory()
      const rectangle = factory.createShape("rectangle", 4, 6)

      return (
        rectangle instanceof Rectangle &&
        rectangle.width === 4 &&
        rectangle.height === 6 &&
        rectangle.type === "rectangle"
      )
    })()
  )

  console.log(
    "3. 创建三角形:",
    (() => {
      const factory = new ShapeFactory()
      const triangle = factory.createShape("triangle", 3, 4, 5, 5)

      return (
        triangle instanceof Triangle &&
        triangle.base === 3 &&
        triangle.height === 4 &&
        triangle.type === "triangle"
      )
    })()
  )

  console.log(
    "4. 圆形面积计算:",
    (() => {
      const circle = new Circle(5)
      const area = circle.getArea()
      const expected = Math.PI * 5 * 5

      return Math.abs(area - expected) < 0.001
    })()
  )

  console.log(
    "5. 圆形周长计算:",
    (() => {
      const circle = new Circle(3)
      const perimeter = circle.getPerimeter()
      const expected = 2 * Math.PI * 3

      return Math.abs(perimeter - expected) < 0.001
    })()
  )

  console.log(
    "6. 矩形面积计算:",
    (() => {
      const rectangle = new Rectangle(4, 6)
      const area = rectangle.getArea()

      return area === 24
    })()
  )

  console.log(
    "7. 矩形周长计算:",
    (() => {
      const rectangle = new Rectangle(4, 6)
      const perimeter = rectangle.getPerimeter()

      return perimeter === 20
    })()
  )

  console.log(
    "8. 三角形面积计算:",
    (() => {
      const triangle = new Triangle(4, 6, 5, 5)
      const area = triangle.getArea()

      return area === 12
    })()
  )

  console.log(
    "9. 三角形周长计算:",
    (() => {
      const triangle = new Triangle(3, 4, 5, 5)
      const perimeter = triangle.getPerimeter()

      return perimeter === 13
    })()
  )

  console.log(
    "10. 获取支持的形状类型:",
    (() => {
      const factory = new ShapeFactory()
      const types = factory.getSupportedTypes()

      return (
        Array.isArray(types) &&
        types.includes("circle") &&
        types.includes("rectangle") &&
        types.includes("triangle")
      )
    })()
  )

  console.log(
    "11. 注册新形状类型:",
    (() => {
      const factory = new ShapeFactory()

      // 创建正方形类
      class Square extends Shape {
        constructor(side) {
          super()
          this.type = "square"
          this.side = side
        }

        getArea() {
          return this.side * this.side
        }

        getPerimeter() {
          return 4 * this.side
        }
      }

      factory.registerShape("square", Square)
      const square = factory.createShape("square", 5)

      return (
        square instanceof Square && square.side === 5 && square.getArea() === 25
      )
    })()
  )

  console.log(
    "12. 错误处理 - 不支持的类型:",
    (() => {
      const factory = new ShapeFactory()

      try {
        factory.createShape("invalid", 1, 2)
        return false
      } catch (e) {
        return true
      }
    })()
  )

  console.log(
    "13. 工厂单例模式:",
    (() => {
      const factory1 = new ShapeFactory()
      const factory2 = new ShapeFactory()

      // 工厂应该可以创建多个实例
      return factory1 !== factory2
    })()
  )

  console.log(
    "14. 形状继承关系:",
    (() => {
      const circle = new Circle(5)
      const rectangle = new Rectangle(4, 6)
      const triangle = new Triangle(3, 4, 5, 5)

      return (
        circle instanceof Shape &&
        rectangle instanceof Shape &&
        triangle instanceof Shape
      )
    })()
  )

  console.log(
    "15. 复杂工厂使用场景:",
    (() => {
      const factory = new ShapeFactory()
      const shapes = [
        factory.createShape("circle", 2),
        factory.createShape("rectangle", 3, 4),
        factory.createShape("triangle", 3, 4, 5, 5)
      ]

      const totalArea = shapes.reduce((sum, shape) => sum + shape.getArea(), 0)
      const expectedArea = Math.PI * 4 + 12 + 6

      return Math.abs(totalArea - expectedArea) < 0.001
    })()
  )

  console.log(
    "16. 形状类型验证:",
    (() => {
      const circle = new Circle(1)
      const rectangle = new Rectangle(1, 1)
      const triangle = new Triangle(1, 1, 1, 1)

      return (
        circle.type === "circle" &&
        rectangle.type === "rectangle" &&
        triangle.type === "triangle"
      )
    })()
  )

  console.log(
    "17. 参数验证:",
    (() => {
      try {
        new Circle(-1) // 负数半径
        return false
      } catch (e) {
        return true
      }
    })()
  )

  console.log(
    "18. 工厂方法链式调用:",
    (() => {
      const factory = new ShapeFactory()

      const shapes = []
      shapes.push(factory.createShape("circle", 1))
      shapes.push(factory.createShape("rectangle", 2, 3))

      return (
        shapes.length === 2 &&
        shapes[0].type === "circle" &&
        shapes[1].type === "rectangle"
      )
    })()
  )

  console.log(
    "19. 动态类型注册和创建:",
    (() => {
      const factory = new ShapeFactory()

      // 创建椭圆类
      class Ellipse extends Shape {
        constructor(a, b) {
          super()
          this.type = "ellipse"
          this.a = a
          this.b = b
        }

        getArea() {
          return Math.PI * this.a * this.b
        }

        getPerimeter() {
          // 近似计算
          return Math.PI * (this.a + this.b)
        }
      }

      factory.registerShape("ellipse", Ellipse)
      const ellipse = factory.createShape("ellipse", 3, 2)

      return (
        ellipse instanceof Ellipse &&
        ellipse.a === 3 &&
        ellipse.b === 2 &&
        factory.getSupportedTypes().includes("ellipse")
      )
    })()
  )

  console.log(
    "20. 工厂模式实际应用:",
    (() => {
      // 模拟图形编辑器
      const factory = new ShapeFactory()
      const canvas = []

      // 用户绘制不同形状
      canvas.push(factory.createShape("circle", 10))
      canvas.push(factory.createShape("rectangle", 20, 15))
      canvas.push(factory.createShape("triangle", 8, 6, 10, 10))

      // 计算画布总面积
      const totalArea = canvas.reduce((sum, shape) => sum + shape.getArea(), 0)

      return canvas.length === 3 && totalArea > 0
    })()
  )

  console.log(
    "21. this上下文测试:",
    (() => {
      const obj = {
        defaultSize: 5,
        createDefaultShape: function(type) {
          const factory = new ShapeFactory()
          return factory.createShape(type, this.defaultSize)
        }
      }
      const circle = obj.createDefaultShape("circle")
      return circle.radius === 5
    })()
  )

  console.log(
    "22. 方法调用this绑定:",
    (() => {
      const obj = {
        prefix: "shape_",
        createNamedShape: function(type, size) {
          const factory = new ShapeFactory()
          const shape = factory.createShape(type, size)
          shape.name = this.prefix + type
          return shape.name
        }
      }
      return obj.createNamedShape("circle", 3) === "shape_circle"
    })()
  )

  console.log(
    "23. 复杂对象this绑定:",
    (() => {
      const obj = {
        config: { defaultRadius: 8 },
        createConfigShape: function() {
          const factory = new ShapeFactory()
          const circle = factory.createShape("circle", this.config.defaultRadius)
          return circle.radius
        }
      }
      return obj.createConfigShape() === 8
    })()
  )
}

testFactoryPattern()
